@file:Suppress("unused")

package com.csw.android.dev_utils.ex

import android.util.TypedValue
import android.view.View
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer

/**
 * View扩展函数
 */
object ViewEx {

    /**
     * 为多个视图设置点击事件
     */
    fun List<View>.setOnClickListener(onClickListener: View.OnClickListener) {
        forEach {
            it.setOnClickListener(onClickListener)
        }
    }

    /**
     * 设置view可见
     *
     * 推荐使用View的扩展属性[View.isVisible]
     */
    fun View.visible() {
        isVisible = true
    }

    /**
     * 设置view不可见但占用位置
     *
     * 推荐使用View的扩展属性[View.invisible]
     */
    fun View.invisible(isInvisible: Boolean = true) {
        this.isInvisible = isInvisible
    }

    /**
     * 设置view为隐藏状态
     *
     * 推荐使用View的扩展属性[View.isVisible]
     */
    fun View.gone(isGone: Boolean = true) {
        isVisible = !isGone
    }

    /**
     * px转dp
     */
    fun View.dp(value: Float): Float {
        return value / resources.displayMetrics.density
    }

    /**
     * px转sp
     */
    fun View.sp(value: Float): Float {
        return value / resources.displayMetrics.scaledDensity
    }

    /**
     * 其他类型转px
     * @param unit 参数数值类型 dp=[TypedValue.COMPLEX_UNIT_DIP],sp=[TypedValue.COMPLEX_UNIT_SP]
     */
    fun View.px(value: Float, unit: Int = TypedValue.COMPLEX_UNIT_DIP): Float {
        return TypedValue.applyDimension(
            unit,
            value,
            resources.displayMetrics
        )
    }

    /**
     * 其他类型转px
     * @param unit 参数数值类型 dp=[TypedValue.COMPLEX_UNIT_DIP],sp=[TypedValue.COMPLEX_UNIT_SP]
     */
    fun View.pxInt(value: Float, unit: Int = TypedValue.COMPLEX_UNIT_DIP) = px(value, unit).toInt()

    /**
     * 在View添加到窗口后订阅LiveData数据变化
     * @param liveData 要订阅的数据对象，可空，可通过返回的封装对象更新
     * @param observer 回调函数
     */
    fun <T> View.subscribeLiveDataAfterAttached(
        liveData: LiveData<T>? = null,
        observer: Observer<T>
    ): AttachedViewObserverHelper<T> {
        return AttachedViewObserverHelper(this, observer).apply {
            this.liveData = liveData
        }
    }

    /**
     * 已附加到窗口的视图 订阅liveData数据变化辅助类，实现仅在视图附加在窗口时才会订阅数据变化
     */
    class AttachedViewObserverHelper<T>(val view: View, val observer: Observer<T>) {
        private var attachListener = object : View.OnAttachStateChangeListener {
            override fun onViewAttachedToWindow(v: View) {
                liveData?.observeForever(observer)
            }

            override fun onViewDetachedFromWindow(v: View) {
                liveData?.removeObserver(observer)
            }
        }

        /**
         * 要订阅的数据
         */
        var liveData: LiveData<T>? = null
            set(value) {
                if (field == value) {
                    return
                }
                field?.removeObserver(observer)
                field = value
                if (view.isAttachedToWindow) {
                    field?.observeForever(observer)
                }
            }

        init {
            view.addOnAttachStateChangeListener(attachListener)
        }
    }
}